#ifndef _NAND_LUT_H
#define _NAND_LUT_H
#include "stdint.h"
#include "nand_w25n.h"

//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

#define NAND_MAX_PAGE_SIZE          4096  	//定义NAND FLASH的最大的PAGE大小（不包括SPARE区），默认4096字节
#define NAND_ECC_SECTOR_SIZE        512 	//执行ECC计算的单元大小，默认512字节
#define NAND_TADL_DELAY             30      //tADL等待延迟,最少70ns


//NAND属性结构体
typedef struct
{
    uint16_t page_size;			//-每页总大小，main区和spare区总和
    uint16_t page_main_size;	//-每页的main区大小
    uint16_t page_spare_size;	//-每页的spare区大小
    uint16_t page_per_block;	//-每个块包含的页数量
    uint16_t block_per_plane;	//-每个plane包含的块数量
    uint16_t block_total;		//-总的块数量
    uint16_t good_block;		//-好块数量
    uint16_t valid_block;		//-有效块数量(供文件系统使用的好块数量)
    uint16_t logic_block_amount;//-逻辑块数
	uint16_t new_block_next;	//-下一个新块起始搜索位置
	uint16_t empty_block;		//-空块
	uint16_t bad_block;			//-坏块
    uint32_t id;				//-NAND FLASH ID
	uint32_t page_read_old;		//-最近一次读取的物理页
    uint16_t *lut;				//-LUT表，用作逻辑块-物理块转换
    uint8_t *buff;				//-缓存
    uint32_t ecc_hard;			//-硬件计算出来的ECC值
    uint32_t *ecc_hdbuf;		//-ECC硬件计算值缓冲区
    uint32_t *ecc_rdbuf;		//-ECC读取的值缓冲区 
    
    struct
    {
        uint8_t (*ecc_error_get)(void); //1-ecc error, 0-ecc not error
        uint8_t (*read_page)( uint32_t page_addr);
        uint8_t (*read_cache)( uint16_t page_addr, uint8_t *dat, uint16_t Len);
        uint8_t (*write_cache)( uint16_t page_addr, const uint8_t *dat, uint16_t Len);
        uint8_t (*program_exe)( uint32_t page_addr);
        uint8_t (*block_erase)( uint32_t block_addr);
        uint8_t (*init)(void);
    } hal;
} nand_attriute;

extern nand_attriute nand_dev; //nand重要参数结构体

/*-备份区数据结构-*/
typedef struct 
{
	uint16_t bad_mark;
	uint16_t lrc;
	uint16_t logic1;
	uint16_t logic2;
	uint16_t ver;
} lut_spare_data_type;

/*-初始化-*/
void nand_lut_open(void);
void nand_lut_close(void);

/*-创建lut-*/
void nand_lut_creat(void);

/*-块擦除-*/
uint8_t nand_lut_block_erase(uint16_t logic_block);

/*-块写，内含坏块管理*/
uint8_t nand_lut_block_write(uint16_t logic_block, uint8_t (*write_dat_get)(uint32_t addr_offset, uint8_t *pdat, uint16_t len)); //-返回1代表错误中断                 

/*-页读-整页-*/
uint8_t nand_lut_page_read(uint32_t logic_page_start, uint8_t *pdat, uint16_t page_len);

/*-任意读-*/
uint8_t nand_lut_inp_read(uint32_t logic_page, uint16_t cell_offset, int32_t dat_len, uint8_t *pdat);

/*-读，地址转换-*/
uint8_t nand_lut_addr_read(uint32_t addr, int32_t dat_len, uint8_t *pdat);

/*-读，初始化-*/
uint8_t nand_lut_read_init(void);

#endif
